﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using itau.im.entidade;
using itau.im.dado;
using EnterpriseLibraryWrapper;
using System.ServiceModel;

namespace itau.im.negocio
{
    public class ConversorTaxas : IConversorTaxas
    {
        #region Métodos

        public IList<CurvaExecucaoPonto> ConvertePUsParaExponencial(IList<CurvaExecucaoPonto> listaPontos, int baseDias)
        {
            for (int i = 0; i < listaPontos.Count; i++)
            {
                // Verifica a quantidade base de dias
                if (baseDias == 252)
                {
                    // Verifica a quantidade de dias corridos
                    listaPontos[i].ValorVertice = ConvertePUParaLinear(listaPontos[i].ValorVertice, baseDias, listaPontos[i].QuantidadeDiasUteis);
                }
                else
                {
                    // Verifica a quantidade de dias corridos
                    listaPontos[i].ValorVertice = ConvertePUParaLinear(listaPontos[i].ValorVertice, baseDias, listaPontos[i].QuantidadeDiasCorridos);
                }

            }

            return listaPontos;
        }

        public IList<CurvaExecucaoPonto> ConverteFatoresDiariosParaLinear(IList<CurvaExecucaoPonto> listaPontos, int baseDias)
        {
            List<CurvaExecucaoPonto> novaListaPontos = null;
            CurvaExecucaoPonto novoPonto = null;

            try
            {
                novaListaPontos = new List<CurvaExecucaoPonto>();

                foreach (CurvaExecucaoPonto curvaExecucaoPonto in listaPontos)
                {
                    novoPonto = new CurvaExecucaoPonto();

                    novoPonto.CodigoCurva = curvaExecucaoPonto.CodigoCurva;
                    novoPonto.DataHoraExecucaoCurva = curvaExecucaoPonto.DataHoraExecucaoCurva;
                    novoPonto.DataInclusaoVigencia = curvaExecucaoPonto.DataInclusaoVigencia;
                    novoPonto.DataVencimento = curvaExecucaoPonto.DataVencimento;
                    novoPonto.IndicadorVertice = curvaExecucaoPonto.IndicadorVertice;
                    novoPonto.QuantidadeDiasCorridos = curvaExecucaoPonto.QuantidadeDiasCorridos;
                    novoPonto.QuantidadeDiasUteis = curvaExecucaoPonto.QuantidadeDiasUteis;
                    novoPonto.ValorVertice = curvaExecucaoPonto.ValorVertice;

                    // Verifica a quantidade base de dias
                    if (baseDias == 252)
                    {
                        // Verifica a quantidade de dias corridos
                        if ((curvaExecucaoPonto.QuantidadeDiasUteis != 0))
                            novoPonto.ValorVertice = (double)100 * ((curvaExecucaoPonto.ValorVertice - 1) * ((double)baseDias / curvaExecucaoPonto.QuantidadeDiasUteis));
                        else
                            novoPonto.ValorVertice = 0;
                    }
                    else
                    {
                        // Verifica a quantidade de dias corridos
                        if ((curvaExecucaoPonto.QuantidadeDiasCorridos != 0))
                            novoPonto.ValorVertice = (double)100 * ((curvaExecucaoPonto.ValorVertice - 1) * ((double)baseDias / curvaExecucaoPonto.QuantidadeDiasCorridos));
                        else
                            novoPonto.ValorVertice = 0;
                    }

                    // Adiciona o objeto na lista 
                    novaListaPontos.Add(novoPonto);
                }

                // Retorna a lista
                return novaListaPontos;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                novoPonto = null;
                novaListaPontos = null;
            }

            return null;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverteFatoresDiariosExponenciais(IList<itau.im.entidade.CurvaExecucaoPonto> listaPontos, int baseDias)
        {
            for (int i = 0; i < listaPontos.Count; i++)
            {
                if (i != 0)
                {
                    // Verifica a quantidade base de dias
                    if (baseDias == 252)
                    {
                        // Verifica a quantidade de dias corridos
                        listaPontos[i].ValorVertice = ConverteFatorDiarioParaExponencial(listaPontos[i].ValorVertice, baseDias, listaPontos[i].QuantidadeDiasUteis);
                    }
                    else
                    {
                        // Verifica a quantidade de dias corridos
                        listaPontos[i].ValorVertice = ConverteFatorDiarioParaExponencial(listaPontos[i].ValorVertice, baseDias, listaPontos[i].QuantidadeDiasCorridos);
                    }
                }
                else
                {
                    listaPontos[i].ValorVertice = 0;
                }
            }

            return listaPontos;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterFatoresDiariosParaTaxasOver(IList<itau.im.entidade.CurvaExecucaoPonto> listaPontos)
        {
            for (int i = 0; i < listaPontos.Count; i++)
            {
                if (i != 0)
                {
                    listaPontos[i].ValorVertice = ConverterFatorDiarioParaOver(listaPontos[i].ValorVertice, listaPontos[i].QuantidadeDiasCorridos);
                }
                else
                {
                    listaPontos[i].ValorVertice = 0;
                }
            }

            return listaPontos;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConvertePUsParaLinear(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices, int baseDias)
        {
            if (baseDias == 252)
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    listaVertices[i].ValorVertice = ConvertePUParaLinear(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasUteis);
                }
            }
            else
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    listaVertices[i].ValorVertice = ConvertePUParaLinear(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasCorridos);
                }
            }

            return listaVertices;
        }


        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterPUsParaFatorDiario(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices)
        {
            for (int i = 0; i < listaVertices.Count; i++)
            {
                if (i != 0)
                {
                    listaVertices[i].ValorVertice = ConverterPUParaFatorDiario(listaVertices[i].ValorVertice);
                }
                else
                {
                    listaVertices[i].ValorVertice = 1;
                }
            }

            return listaVertices;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverteFatoresDiariosParaPU(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices)
        {
            for (int i = 0; i < listaVertices.Count; i++)
            {
                if (i != 0)
                {
                    listaVertices[i].ValorVertice = ConverterFatorDiarioParaPU(listaVertices[i].ValorVertice);
                }
                else
                {
                    listaVertices[i].ValorVertice = 0;
                }
            }

            return listaVertices;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterTaxasExponenciaisParaFatorDiario(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices, int baseDias)
        {
            if (baseDias == 252)
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    if (i != 0)
                    {
                        listaVertices[i].ValorVertice = ConverterTaxaExponencialParaFatorDiario(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasUteis);
                    }
                    else
                    {
                        listaVertices[i].ValorVertice = 1;
                    }
                }
            }
            else
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    if (i != 0)
                    {
                        listaVertices[i].ValorVertice = ConverterTaxaExponencialParaFatorDiario(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasCorridos);
                    }
                    else
                    {
                        listaVertices[i].ValorVertice = 1;
                    }
                }
            }

            return listaVertices;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterTaxasLinearesParaFatorDiario(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices, int baseDias)
        {
            if (baseDias == 252)
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    if (i != 0)
                    {
                        listaVertices[i].ValorVertice = ConverterTaxaLinearParaFatorDiario(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasUteis);
                    }
                    else
                    {
                        listaVertices[i].ValorVertice = 1;
                    }
                }
            }
            else
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    if (i != 0)
                    {
                        listaVertices[i].ValorVertice = ConverterTaxaLinearParaFatorDiario(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasCorridos);
                    }
                    else
                    {
                        listaVertices[i].ValorVertice = 1;
                    }
                }
            }

            return listaVertices;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterTaxasOverParaFatorDiario(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices)
        {
            for (int i = 0; i < listaVertices.Count; i++)
            {
                if (i != 0)
                {
                    listaVertices[i].ValorVertice = ConverterTaxaOverParaFatorDiario(listaVertices[i].ValorVertice, listaVertices[i].QuantidadeDiasCorridos);
                }
                else
                {
                    listaVertices[i].ValorVertice = 1;
                }
            }

            return listaVertices;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterTaxasExponenciaisParaPU(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices, int baseDias)
        {
            if (baseDias == 252)
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    listaVertices[i].ValorVertice = ConverterTaxaExponencialParaPU(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasUteis);
                }
            }
            else
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    listaVertices[i].ValorVertice = ConverterTaxaExponencialParaPU(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasCorridos);
                }
            }

            return listaVertices;
        }

        public IList<itau.im.entidade.CurvaExecucaoPonto> ConverterTaxasLinearesParaPU(IList<itau.im.entidade.CurvaExecucaoPonto> listaVertices, int baseDias)
        {
            if (baseDias == 252)
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    listaVertices[i].ValorVertice = ConverterTaxaLinearParaPU(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasUteis);
                }
            }
            else
            {
                for (int i = 0; i < listaVertices.Count; i++)
                {
                    listaVertices[i].ValorVertice = ConverterTaxaLinearParaPU(listaVertices[i].ValorVertice, baseDias, listaVertices[i].QuantidadeDiasCorridos);
                }
            }

            return listaVertices;
        }

        public double ConverterFatorDiarioParaLinear(double Fator_diario, long Dias_Ano, long NU_DIAS)
        {
            double retorno = 0.0;

            if (Fator_diario != 0)
            {
                retorno = (double)100 * (Fator_diario - 1) * ((double)Dias_Ano / NU_DIAS);
            }

            return retorno;
        }

        public double ConverterFatorDiarioParaExponencial(double Fator_diario, long Dias_Ano, long NU_DIAS)
        {
            double retorno = 0.0;

            if (Fator_diario != 0)
            {
                retorno = (double)100 * (Math.Pow(Fator_diario, ((double)Dias_Ano / NU_DIAS)) - 1);
            }

            return retorno;
        }

        public double ConverterFatorDiarioParaOver(double Fator_diario, long NU_DIAS)
        {
            double retorno = 0.0;

            if (Fator_diario != 0)
            {
                retorno = (double)3000 * (Math.Pow(Fator_diario, ((double)NU_DIAS / 1)) - 1);
            }

            return retorno;
        }

        public double ConverterFatorDiarioParaPU(double Fator_Desconto)
        {
            double retorno = 0.0;

            if (Fator_Desconto != 0)
            {
                retorno = (double)100000 / Fator_Desconto;
            }

            return retorno;
        }

        public double ConverterTaxaExponencialParaFatorDiario(Double Taxa_Exponencial, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Dias_Ano != 0)
            {
                retorno = (double)Math.Pow(1 + ((double)Taxa_Exponencial / 100), ((double)Nu_Dias / Dias_Ano));
            }

            return retorno;
        }

        public double ConverterTaxaLinearParaFatorDiario(double Taxa_Linear, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Dias_Ano != 0)
            {
                retorno = 1 + ((double)Taxa_Linear / 100) * ((double)Nu_Dias / Dias_Ano);
            }

            return retorno;
        }

        public double ConverterTaxaOverParaFatorDiario(double Taxa_Over, long Nu_Dias)
        {
            return Math.Pow((((double)Taxa_Over / 3000) + 1), ((double)Nu_Dias / 1));
        }

        public double ConverterPUParaFatorDiario(double PU)
        {
            double retorno = 0.0;

            if (PU != 0)
            {
                retorno = (double)100000 / PU;
            }

            return retorno;
        }

        public double ConverterTaxaLinearParaPU(double Taxa_Linear, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Dias_Ano != 0)
            {
                retorno = (double)100000 / ((Taxa_Linear * ((double)Nu_Dias / Dias_Ano)) + 1);
            }

            return retorno;
        }

        public double ConverterTaxaExponencialParaPU(double Taxa_Exponencial, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Dias_Ano != 0)
            {
                retorno = (double)100000 / Math.Pow((Taxa_Exponencial + 1), ((double)Nu_Dias / Dias_Ano));
            }

            return retorno;
        }

        public double ConvertePUParaLinear(double PU, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Nu_Dias != 0)
            {
                retorno = ((100000 / PU) - 1) * (Dias_Ano / Nu_Dias);
            }

            return retorno;
        }

        public double ConvertePUParaExponencial(double PU, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Nu_Dias != 0)
            {
                retorno = Math.Pow(((double)100000 / PU), ((double)Dias_Ano / Nu_Dias)) - 1;
            }

            return retorno;
        }

        public double ConverteFatorDiarioParaExponencial(double Fator_Diario, int Dias_Ano, long Nu_Dias)
        {
            double retorno = 0.0;

            if (Nu_Dias != 0)
            {
                retorno = (double)100 * (Math.Pow(Fator_Diario, (((double)Dias_Ano / Nu_Dias))) - 1);
            }

            return retorno;
        }

        #endregion
    }
}
